/*
 * Copyright (c) 2002-2007, Mairie de Paris
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice
 *     and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright notice
 *     and the following disclaimer in the documentation and/or other materials
 *     provided with the distribution.
 *
 *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * License 1.0
 */
package fr.paris.lutece.plugins.customisation.service.tab;

import fr.paris.lutece.plugins.customisation.business.portlet.PersonalPortlet;
import fr.paris.lutece.plugins.customisation.business.portlet.PersonalPortletHome;
import fr.paris.lutece.plugins.customisation.business.tab.CustomisationTab;
import fr.paris.lutece.plugins.customisation.business.tab.CustomisationTabHome;
import fr.paris.lutece.plugins.customisation.dnd.DragAndDropCodeBuilder;
import fr.paris.lutece.plugins.customisation.service.CustomisationService;
import fr.paris.lutece.plugins.customisation.web.constants.CustomisationMarkers;
import fr.paris.lutece.plugins.customisation.web.constants.CustomisationParameters;
import fr.paris.lutece.plugins.customisation.web.constants.CustomisationProperties;
import fr.paris.lutece.portal.business.portlet.Portlet;
import fr.paris.lutece.portal.business.portlet.PortletHome;
import fr.paris.lutece.portal.business.style.ModeHome;
import fr.paris.lutece.portal.business.style.PageTemplate;
import fr.paris.lutece.portal.business.style.PageTemplateHome;
import fr.paris.lutece.portal.business.style.StyleHome;
import fr.paris.lutece.portal.business.stylesheet.StyleSheet;
import fr.paris.lutece.portal.business.stylesheet.StyleSheetHome;
import fr.paris.lutece.portal.service.html.XmlTransformerService;
import fr.paris.lutece.portal.service.message.SiteMessageException;
import fr.paris.lutece.portal.service.security.LuteceUser;
import fr.paris.lutece.portal.service.security.SecurityService;
import fr.paris.lutece.portal.service.template.AppTemplateService;
import fr.paris.lutece.portal.service.util.AppPropertiesService;
import fr.paris.lutece.util.html.HtmlTemplate;

import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;



/**
 * This class provides a service that build tab
 */
public class TabService extends XmlTransformerService
{
    // Markers
    private static final String MARK_PAGE_TEMPLATE_CONTENT = "page_content_col"; // Columns of the template
    private static final String MARK_PORTLET = "portlet"; // One portlet
    private static final String MARK_CUSTOMISATION = "customisation";
    private static final String MARK_CUSTOMISATION_PORTLET_STYLES_COMBO = "portlet_style_combo"; // Styles for a portlet
    private static final String MARK_CUSTOMISATION_MODE_SELECTED = "mode_selected"; // Activ mode
    private static final String MARK_CUSTOMISATION_ONE_TAB = "one_tab"; // One tab

    // Templates
    private static final String TEMPLATE_ADMIN_BUTTONS = "/skin/plugins/customisation/customisation_admin_buttons.html";
    private static final String TEMPLATE_CUSTOMISATION_CONTENT_PAGE_EMPTY = "skin/plugins/customisation/customisation_content_page_empty.html";
    //added for drag and drop
    private static final String TEMPLATE_DRAG_AND_DROP = "skin/plugins/customisation/page_template_dynamic.html";
    
    // Constants
    private static String _strUserName;
    private static final String MARK_THEME_CSS = "theme_css";
    private static final String MARK_THEME_IMAGES = "theme_images";
    private static final String PROPERTY_PREFIX = "themes.";
    private static final String PROPERTY_SUFFIX_CSS = ".css";
    private static final String PROPERTY_SUFFIX_IMAGES = ".images";
    private static final String DEFAULT_THEME = "default";

    /**
     * Returns the content of the current tab
     *
     * @param request the http request
     * @param nModePage the selected mode
     * @param nIdTab the current tab identifier
     * @return the content of the current tab
     */
    public static String getTabContent( HttpServletRequest request, int nModePage, int nIdTab )
    {
        LuteceUser user = SecurityService.getInstance(  ).getRegisteredUser( request );
        _strUserName = user.getName(  );

        String strColumn = AppPropertiesService.getProperty( CustomisationProperties.PAGE_COLUMN_NUM_MAX );
        int nColumn = Integer.parseInt( strColumn );
        String[] arrayContent = new String[nColumn];

        HashMap<String, Object> model = new HashMap<String, Object>(  );
        model.put( MARK_CUSTOMISATION_MODE_SELECTED, nModePage ); // Selected mode

        for ( int i = 0; i < nColumn; i++ )
        {
            arrayContent[i] = "";
        }

        List<CustomisationTab> listUserTab = CustomisationTabHome.getTabUser( _strUserName );
        int nTabId = nIdTab;

        // Obtain the file template for this tab
        if ( nIdTab == CustomisationParameters.CUSTOMISATION_ANY_TAB )
        {
            nTabId = listUserTab.get( 0 ).getIdTab(  );
        }

        CustomisationTab tab = CustomisationTabHome.findByPrimaryKey( nTabId );

        model.put( MARK_CUSTOMISATION_ONE_TAB, tab );

        PageTemplate pageTemp = PageTemplateHome.findByPrimaryKey( tab.getIdTemplate(  ) );
        String strFileTemplateByTab = pageTemp.getFile(  );
    
        // To obtain the list of portlets of this tab
        List<PersonalPortlet> listPortletByTab = PersonalPortletHome.findByPrimaryTabKey( _strUserName, nTabId );

        String strPortletContent = null; // Content of a portlet
        
        DragAndDropCodeBuilder dragAndDropBuilder=null;
        /* if this tab uses the drag and drop template */
        if(strFileTemplateByTab.equals(TEMPLATE_DRAG_AND_DROP)){
        	/* enable drag and drop */
        	dragAndDropBuilder=new DragAndDropCodeBuilder();
        }

        // Detail for each portlet
        for ( int i = 0; i < listPortletByTab.size(  ); i++ )
        {
        	
            Portlet portlet = PortletHome.findByPrimaryKey( listPortletByTab.get( i ).getId(  ) );

            PersonalPortlet personalPortlet = PersonalPortletHome.findByPrimaryKeyTabKey( listPortletByTab.get( i )
                                                                                                          .getId(  ),
                    nTabId );

            int nColUser = personalPortlet.getColumn(  );
            int nStyleUser = personalPortlet.getStyleId(  );
            int nDisplayTitleUser = personalPortlet.getDisplayPortletTitle(  );
            int nModeDefault = personalPortlet.getModeDefault(  );
            int nOrdUser = personalPortlet.getOrder(  );

            portlet.setColumn( nColUser );
            portlet.setOrder( nOrdUser );

            List<StyleSheet> listStyleSheet = (List<StyleSheet>) StyleHome.getStyleSheetList( nStyleUser );
            StyleSheet stylesheet = StyleSheetHome.findByPrimaryKey( listStyleSheet.get( 0 ).getId(  ) );

            if ( nModeDefault != 0 )
            {
                portlet.setDisplayPortletTitle( nDisplayTitleUser );
                portlet.setStyleId( nStyleUser );

                try
                {
                    strPortletContent = XmlTransformerService.transformBySource( portlet.getXml( request ),
                            stylesheet.getSource(  ), portlet.getXslParams(  ), ModeHome.getOuputXslProperties( 0 ) );
                }
                catch ( SiteMessageException e )
                {
                    e.printStackTrace(  );
                }
            }
            else
            {
                try
                {
                    strPortletContent = XmlTransformerService.transformBySource( portlet.getXml( request ),
                            portlet.getXslSource( 1 ), portlet.getXslParams(  ), ModeHome.getOuputXslProperties( 0 ) );
                }
                catch ( SiteMessageException e )
                {
                    e.printStackTrace(  );
                }
            }

            if ( nModePage != 0 )
            {
            	
                HashMap<String, Object> hModel = new HashMap<String, Object>(  );
                hModel.put( MARK_PORTLET, portlet );
                hModel.put( MARK_CUSTOMISATION, personalPortlet );
                hModel.put( CustomisationMarkers.CUSTOMISATION_PORTLET_ORDER_COMBO,
                    CustomisationService.getOrdersList(  ) );
                hModel.put( CustomisationMarkers.CUSTOMISATION_PORTLET_COLUMN_COMBO,
                    CustomisationService.getColumnsList(  ) );
                hModel.put( MARK_CUSTOMISATION_PORTLET_STYLES_COMBO,
                    PortletHome.getStylesList( portlet.getPortletTypeId(  ) ) );

                CustomisationTab currentTab = CustomisationTabHome.findByPrimaryKey( nTabId );
                hModel.put( MARK_CUSTOMISATION_ONE_TAB, currentTab );

                HtmlTemplate templateAdminButtons = AppTemplateService.getTemplate( TEMPLATE_ADMIN_BUTTONS,
                        request.getLocale(  ), hModel );
                strPortletContent = strPortletContent + templateAdminButtons.getHtml(  );
            }
            
            /* if drag and drop is enabled */
            if(dragAndDropBuilder!=null){
            	strPortletContent = dragAndDropBuilder.surroundWithLiTag(personalPortlet.getId(),strPortletContent);
            }
            
            int nCol = nColUser - 1;

            if ( nCol < nColumn )
            {
                arrayContent[nCol] += strPortletContent;
            }
        }

        HashMap rootModel = new HashMap(  );

        for ( int j = 0; j < nColumn; j++ )
        {
            rootModel.put( MARK_PAGE_TEMPLATE_CONTENT + ( j + 1 ), arrayContent[j] );
        }
        
        /* if drag and drop is enabled */
        if(dragAndDropBuilder!=null){
        	/* add the dnd model to the tab template root model */
        	dragAndDropBuilder.buildDndTemplateModel(rootModel,tab);
        }
        
        HtmlTemplate templateContent = null;

        if ( listPortletByTab.size(  ) != 0 )
        {
        	//ici on construit un template 
            templateContent = AppTemplateService.getTemplate( strFileTemplateByTab, request.getLocale(  ), rootModel );
        }
        else
        {
            fillTemplate( model, tab );

            templateContent = AppTemplateService.getTemplate( TEMPLATE_CUSTOMISATION_CONTENT_PAGE_EMPTY,
                    request.getLocale(  ), model );
        }
        
        return templateContent.getHtml(  );
    }

    /**
     * Substitue specific Freemarker markers in the page template
     *
     * @param model the HashMap containing markers to substitute
     * @param tab the current tab
     */
    public static void fillTemplate( HashMap<String, Object> model, CustomisationTab tab )
    {
        // The code_theme of the page
        String strTheme = tab.getCodeTheme(  );

        // If code_theme is null, used the default files ( css and images )
        if ( ( strTheme == null ) || ( strTheme.equals( "" ) ) )
        {
            strTheme = DEFAULT_THEME;
        }

        String strCss = AppPropertiesService.getProperty( PROPERTY_PREFIX + strTheme + PROPERTY_SUFFIX_CSS );
        model.put( MARK_THEME_CSS, strCss );

        String strImages = AppPropertiesService.getProperty( PROPERTY_PREFIX + strTheme + PROPERTY_SUFFIX_IMAGES );
        model.put( MARK_THEME_IMAGES, strImages );
    }
}
